package net.dreamlu.ext.base;

import java.util.List;

import com.jfinal.core.JFinal;
import com.jfinal.kit.HashKit;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;

@SuppressWarnings("rawtypes")
public class BaseModel<M extends Model> extends Model<M> {
	
	private static final long serialVersionUID = -6215428115177000482L;
	static boolean devMode = JFinal.me().getConstants().getDevMode();
	
	/**
	 * Find first model by cache. I recommend add "limit 1" in your sql.
	 * @see #findFirst(String, Object...)
	 * @param cacheName the cache name
	 * @param sql an SQL statement that may contain one or more '?' IN parameter placeholders
	 * @param paras the parameters of sql
	 */
	public M findFirstByCache(String cacheName, String sql, Object... paras) {
		String key = initCache(null, null, sql, null, paras);
		return findFirstByCache(cacheName, key, sql, paras);
	}
	
	/**
	 * @see #findFirstByCache(String, Object, String, Object...)
	 */
	public M findFirstByCache(String cacheName, String sql) {
		String key = initCache(null, null, sql, null);
		return findFirstByCache(cacheName, key, sql);
	}
	
	/**
	 * Find model by cache.
	 * @see #find(String, Object...)
	 * @param cacheName the cache name
	 * @param key the key used to get date from cache
	 * @return the list of Model
	 */
	public List<M> findByCache(String cacheName, String sql, Object... paras) {
		String key = initCache(null, null, sql, null, paras);
		return findByCache(cacheName, key, sql, paras);
	}
	
	/**
	 * Paginate by cache.
	 * @see #paginate(int, int, String, String, Object...)
	 * @param cacheName the cache name
	 * @return Page
	 */
	public Page<M> paginateByCache(String cacheName, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) {
		
		String key = initCache(pageNumber, pageSize, select, sqlExceptSelect, paras);
		Page<M> result = null;
		if (devMode) {
			result = paginate(pageNumber, pageSize, select, sqlExceptSelect, paras);
		} else {
			result = paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect);
		}
		return result;
	}
	
	/**
	 * memcache key 使用sql和paras
	 * @param pageNumber
	 * @param pageSize
	 * @param select
	 * @param sqlExceptSelect
	 * @param paras
	 * @return	设定文件
	 * @return String	返回类型
	 * @throws
	 */
	private String initCache(Integer pageNumber, Integer pageSize, String select, String sqlExceptSelect, Object... paras) {
		StringBuilder key = new StringBuilder(select);
		if (null != pageNumber) {
			key.append(pageNumber);
		}
		if (null != pageSize) {
			key.append(pageSize);
		}
		if (null != sqlExceptSelect) {
			key.append(sqlExceptSelect);
		}
		if (null != paras) {
			for (Object object : paras) {
				key.append(object);
			}
		}
		return HashKit.md5(key.toString());
	}
}
